﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 对象_用父类声明_却用子类实例化
{
    //C#中,为什么一个对象可以用父类声明,用子类实例化,这个对象到底是什么类型的
    //子类的，这种情况多用于多态，好处在于，不管有几个子类继承了这个父类，声明的时候只需用父类声明，
    //但是要指向子类对象。调用重载过的方法时就会自动调用在子类重写的方法。
    //调用方法时，如果父类方法被实例化的子类重写，那么就会自动调用子类重写了的方法

    /// <summary>  
    /// 父类  
    /// </summary>  
    public class ParentClass
    {

        public virtual void ParVirMethod()
        {
            Console.WriteLine("父类的方法...");
        }
    }

    /// <summary>  
    /// 子类1  
    /// </summary>  
    public class ChildClass1 : ParentClass
    {

        public override void ParVirMethod()
        {
            Console.WriteLine("子类1的方法...");
        }
    }

    /// <summary>  
    /// 子类2  
    /// </summary>  
    public class ChildClass2 : ParentClass
    {
        public new void ParVirMethod()
        {
            Console.WriteLine("子类2的方法...");
        }

        public void Test()
        {
            Console.WriteLine("子类2的其他方法...");
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            ParentClass par = new ChildClass1();
            ParentClass par1 = new ParentClass();
            ChildClass1 par2 = new ChildClass1();
            //par.ParVirMethod(); //结果："子类1的方法"，调用子类的方法，实现了多态


            //par = new ChildClass2();
            //par.ParVirMethod(); //结果："父类的方法"，调用父类的方法，没有实现多态 

            Console.ReadKey();
        }
    }


//    应用举例

//有这样的需要的, 比如 People 类有一个 Run 方法，Man 和 Woman 这两个类都是继承自 People 的类，并且都重写(override)了 Run 这个方法(男人女人跑起步来不一样)。
//现在有一群人一起跑步，有男人有女人。
//我们可以把这些都装进一个People数组(假设为peoples)。
//然后:
//foreach(People p in peoples) // peoples中对象不同（即有男有女），用于实例化的子类就不同。
//{
//    p.Run(); // 故而，调用的方法也不同，实现了多态
//}
//由于多态性,在调用 p.Run() 的时候 p 对象本身如果是男人就会自动调用男人的 Run 方法,是女人就会调用女人的 Run 方法。
}
